#include "Slider.h"
#include "../../ImageManager.h"
#include "../../Rectangle.h"
#include "../Manager.h"

extern bool Collision(const core::Rectangle& a, const core::Rectangle&b);

namespace PickinOpenSticks {
    namespace Ui {

        void Slider::SetBackgroundImage(const std::string &filename) {
            sprite.SetImage(ImageManager::GetSingleton().GetImage(filename, filename));
        }

        void Slider::SetCursorImage(const std::string &filename) {
            cursor.SetImage(ImageManager::GetSingleton().GetImage(filename, filename));
        }

        void Slider::SetDefaultImage() {
            sprite.SetImage(ImageManager::GetSingleton().GetImage("assets/gfx/slider.png", "default_slider"));
            cursor.SetImage(ImageManager::GetSingleton().GetImage("assets/gfx/slider-cursor.png", "default_slider_cursor"));

            pos.x = (int) sprite.GetPosition().x;
            pos.y = (int) sprite.GetPosition().y;
            pos.w = (int) sprite.GetSize().x;
            pos.h = (int) sprite.GetSize().y;
        }

        void Slider::OnClickPressed(sf::Event *event) {
            sf::Vector2f pos = Manager::GetSingleton().ConvertCoords(event->MouseButton.X, event->MouseButton.Y);
            if (Collision(core::Rectangle(pos, sf::Vector2f(2, 2)),
                    core::Rectangle(cursor.GetPosition(), cursor.GetSize()))) {

                //start drag
                drag = true;

                sf::Vector2f spot = Manager::GetSingleton().ConvertCoords(event->MouseButton.X, event->MouseButton.Y);

                //set the hotspot (relative to the position of the cursor)
                hotSpotX = spot.x - cursor.GetPosition().x;
                hotSpotY = spot.y - cursor.GetPosition().y;
            }//if the click location wasn't on the cursor..
            else {
                sf::Vector2f spot = Manager::GetSingleton().ConvertCoords(event->MouseButton.X, event->MouseButton.Y);

                if ((int) spot.x > cursor.GetPosition().x) {
                    curValue += (upperLimit - lowerLimit) / 10;
                    if (curValue > upperLimit) curValue = upperLimit;
                } else {
                    curValue -= (upperLimit - lowerLimit) / 10;
                    if (curValue < lowerLimit) curValue = lowerLimit;
                }
            }
        }

        void Slider::Update(int diff) {

            Widget::Update(diff);
            if (curValue <= lowerLimit) curValue = lowerLimit;
            else if (curValue >= upperLimit) curValue = upperLimit;

            //update the cursor position
            int xAxisDisplacement = std::abs(curValue - lowerLimit); //do I need the abs value ?
            int maxNumbersPosible = upperLimit - lowerLimit;
            double percent = xAxisDisplacement / (double) maxNumbersPosible;

            //calculate position for the cursor
            int w = (int) sprite.GetSize().x - (int) cursor.GetSize().x;
            //int x = (int)sprite.GetPosition().x; int y = (int)sprite.GetPosition().y;

            //calculate the x-axis displacement
            int xDisp = percent*w;

            //move the cursor
            cursor.SetPosition(sprite.GetPosition().x + xDisp, sprite.GetPosition().y);


        }

        void Slider::Draw(sf::RenderTarget* target) {
            target->Draw(sprite);
            target->Draw(cursor);
        }

        void Slider::OnClickReleased(sf::Event *event) {
            drag = false;
        }

        void Slider::OnOtherEvents(sf::Event* event) {
            if (event->Type == sf::Event::MouseMoved) {
                int mouseX = event->MouseMove.X;
                int mouseY = event->MouseMove.Y;
                sf::Vector2f mouse = Manager::GetSingleton().ConvertCoords(mouseX, mouseY);
                mouseX = (int) mouse.x;
                mouseY = (int) mouse.y;
                if (drag) {
                    //calculate where the cursor would land
                    int landSpotX = mouseX - hotSpotX;

                    //if it lands out of bonds.. correct that !
                    if (landSpotX > pos.x + pos.w - cursor.GetSize().x) {
                        landSpotX = pos.x + pos.w - cursor.GetSize().x;
                        curValue = upperLimit;
                    } else if (landSpotX < pos.x) {
                        landSpotX = pos.x;
                        curValue = lowerLimit;
                    } else {
                        double percent = (float) ((landSpotX - pos.x) / (float) (pos.w - cursor.GetSize().x));
                        int maxNumbers = upperLimit - lowerLimit;

                        curValue = lowerLimit + maxNumbers*percent;
                    }



                    //now sets the position of the cursor
                    cursor.SetPosition(landSpotX, cursor.GetPosition().y);
                }
            }
        }
    }
}
